#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <sys/select.h>
#include <poll.h>

int main(int argc, const char *argv[])
{
  // 创建套接字
  int lfd = socket(AF_INET, SOCK_STREAM, 0);
  // 绑定本地IP和端口
  struct sockaddr_in serv;
  memset(&serv, 0, sizeof(serv));
  serv.sin_port = htons(8888);
  serv.sin_addr.s_addr = INADDR_ANY;
  serv.sin_family = AF_INET;
  bind(lfd, (struct sockaddr*)&serv, sizeof(serv));

  // 监听
  listen(lfd, 128);

  // 等待接收连接请求
  struct sockaddr_in client;
  int len = sizeof(client);

  struct pollfd allfd[1024];
  int max_index = 0;
  for(int i=0; i<1024; ++i)
  {
    allfd[i].fd = -1;
    allfd[i].events = POLLIN;
  }
  allfd[0].fd = lfd;

  while(1)
  {

    int i=0;
    int ret = poll(allfd, max_index+1, -1);    
    if(ret == -1)
    {
      printf("error \n");
      exit(1);
    }
    if(allfd[0].revents & POLLIN)
    {
      // 如果有新的连接到达了
      char ip[64];
      int cfd = accept(lfd, (struct sockaddr*)&client, &len);
      printf("client IP: %s, port: %d\n", inet_ntop(AF_INET, &client.sin_addr.s_addr, ip, sizeof(ip)), ntohs(client.sin_port));
      if(cfd == -1)
      {
        printf("客户端连接失败\n");
        exit(1);
      }
      for(int i=0; i<1024; ++i)
      {
        if(allfd[i].fd == -1)
        {
          allfd[i].fd = cfd;
          break;
        }
      }
      max_index = max_index < i ? i : max_index;
    }

    for(int i=1; i<=max_index; ++i)
    {
      int fd = allfd[i].fd;
      if(fd == -1)
      {
        continue;
      }
      if(allfd[i].revents & POLLIN)
      {
        char buf[1024] = {0};
        // 如果有数据到来
        int len = recv(i, buf, sizeof(buf), 0);
        if(len == -1)
        {
          printf("read error\n");
          exit(1);
        }
        else if(len == 0)
        {
          printf("客户端主动断开了链接\n");
          // 从文件描述附表中删除 当前文件描述符
          // FD_CLR(i, &reads);
          allfd[i].fd = -1;
          close(fd);
        }
        else
        {
          printf("recv %s\n", buf);
          send(i, buf, strlen(buf)+1, 0);
        }
      }
    }
  }
  close(lfd);

  
  return 0;
}
